﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.JointVariableLimitsEditor.CUiJVLEditorGrid
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using C1.Win.C1FlexGrid;
using C1.Win.C1FlexGrid.Util.BaseControls;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using Tecnomatix.Engineering.Ui;
using Tecnomatix.Engineering.Ui48;
using UiInternalControls.WindowsFormsControls;


namespace DnProcessSimulateCommands.JointVariableLimitsEditor;

internal class CUiJVLEditorGrid : TxFlexGrid
{
  internal const string N_COL_NAME = "N:";
  internal const string X_COL_NAME = "X";
  internal const string Y_COL_NAME = "Y";
  private CApJVLEditorViewModel _viewModel;
  private int _internalSelectionChangeCounter;
  private int _viewModelSelectionChangeCounter;
  private int _activeRow = -1;
  private int _nCol = -1;
  private int _xCol = -1;
  private int _yCol = -1;
  private bool _parentFormKeyPreview = true;
  private TxErrorCtrl _errorTooltip;
  private Color _editorBackColor;
  private int _editorRow = -1;
  private int _editorCol = -1;
  private bool _editorValidState = true;
  private object _cellValueBeforeEdit;
  private bool _emptyRowAdded;
  private IContainer components;

  internal event EventHandler SelectionChanged;

  internal event EventHandler CanDoActionChanged;

  internal event EventHandler DataUpdated;

  public CUiJVLEditorGrid()
  {
    this.InitializeComponent();
    this.init();
  }

  public CUiJVLEditorGrid(IContainer container)
  {
    container.Add((IComponent) this);
    this.InitializeComponent();
    this.init();
  }

  internal CApJVLEditorViewModel ViewModel
  {
    get => this._viewModel;
    set
    {
      if (this._viewModel == value)
        return;
      this.disconnectFromViewModel();
      this._viewModel = value;
      this.connectToViewModel();
    }
  }

  internal bool IsEditing => ((C1FlexGridBase) this).Editor != null;

  internal bool IsValid
  {
    get
    {
      bool isValid = false;
      if (this._viewModel != null && (!this.IsEditing || this._editorValidState))
        isValid = true;
      return isValid;
    }
  }

  internal bool CanDoAction => this.IsValid && !this.IsEditing;

  internal bool CanDeleteActiveSelection
  {
    get
    {
      bool deleteActiveSelection = false;
      if (this.CanDoAction && ((RowColCollection) ((C1FlexGridBase) this).Rows.Selected).Count > 0)
      {
        if (((RowColCollection) ((C1FlexGridBase) this).Rows.Selected).Count > 1)
        {
          deleteActiveSelection = true;
        }
        else
        {
          Row emptyRow = this.EmptyRow;
          if (emptyRow != null && ((C1FlexGridBase) this).Rows.Selected[0] == emptyRow)
          {
            double? x = new double?();
            double? y = new double?();
            this.queryEmptyRow(out x, out y);
            if (x.HasValue || y.HasValue)
              deleteActiveSelection = true;
          }
          else
            deleteActiveSelection = true;
        }
      }
      return deleteActiveSelection;
    }
  }

  internal bool CanMoveItemsUp
  {
    get
    {
      bool canMoveItemsUp = false;
      if (this.CanDoAction && ((RowColCollection) ((C1FlexGridBase) this).Rows).Count > ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed && ((RowColCollection) ((C1FlexGridBase) this).Rows.Selected).Count >= 1)
      {
        bool flag = false;
        Row emptyRow = this.EmptyRow;
        if (emptyRow != null)
          flag = ((RowColCollection) ((C1FlexGridBase) this).Rows.Selected).Contains((RowCol) emptyRow);
        if (!flag)
          canMoveItemsUp = !((RowColCollection) ((C1FlexGridBase) this).Rows.Selected).Contains((RowCol) ((C1FlexGridBase) this).Rows[((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed]);
      }
      return canMoveItemsUp;
    }
  }

  internal bool CanMoveItemsDown
  {
    get
    {
      bool canMoveItemsDown = false;
      if (this.CanDoAction && ((RowColCollection) ((C1FlexGridBase) this).Rows).Count > ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed && ((RowColCollection) ((C1FlexGridBase) this).Rows.Selected).Count >= 1)
      {
        bool flag = false;
        Row emptyRow = this.EmptyRow;
        if (emptyRow != null)
          flag = ((RowColCollection) ((C1FlexGridBase) this).Rows.Selected).Contains((RowCol) emptyRow);
        if (!flag)
        {
          int num = emptyRow != null ? ((RowCol) emptyRow).Index - 1 : ((RowColCollection) ((C1FlexGridBase) this).Rows).Count - 1;
          if (num >= ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed)
            canMoveItemsDown = !((RowColCollection) ((C1FlexGridBase) this).Rows.Selected).Contains((RowCol) ((C1FlexGridBase) this).Rows[num]);
        }
      }
      return canMoveItemsDown;
    }
  }

  internal void LoadData() => this.loadViewModelData();

  internal void DeleteActiveSelection()
  {
    if (!this.CanDeleteActiveSelection)
      return;
    this.deleteActiveSelection();
  }

  internal void MoveItemsUp()
  {
    if (!this.CanMoveItemsUp)
      return;
    this.moveItemsUp();
  }

  internal void MoveItemsDown()
  {
    if (!this.CanMoveItemsDown)
      return;
    this.moveItemsDown();
  }

  private void init()
  {
    ((Control) this).CausesValidation = false;
    ((C1FlexGridBase) this).EditOptions = (EditFlags) (((C1FlexGridBase) this).EditOptions & -9);
    this.storeParentFormKeyPreview();
    this.registerToGridEvents();
  }

  private void storeParentFormKeyPreview()
  {
    Form form = ((Control) this).FindForm();
    if (form == null)
      return;
    this._parentFormKeyPreview = form.KeyPreview;
  }

  private void suspendParentFormKeyPreview()
  {
    Form form = ((Control) this).FindForm();
    if (form == null)
      return;
    this._parentFormKeyPreview = form.KeyPreview;
    form.KeyPreview = false;
  }

  private void resumeParentFormKeyPreview()
  {
    Form form = ((Control) this).FindForm();
    if (form == null)
      return;
    form.KeyPreview = this._parentFormKeyPreview;
  }

  private void initColumns()
  {
    this._nCol = ((C1FlexGridBase) this).Cols.Contains("N:") ? ((RowCol) ((C1FlexGridBase) this).Cols["N:"]).Index : -1;
    this._xCol = ((C1FlexGridBase) this).Cols.Contains("X") ? ((RowCol) ((C1FlexGridBase) this).Cols["X"]).Index : -1;
    this._yCol = ((C1FlexGridBase) this).Cols.Contains("Y") ? ((RowCol) ((C1FlexGridBase) this).Cols["Y"]).Index : -1;
  }

  private void loadViewModelData()
  {
    ((ScrollableControl) this).BeginUpdate();
    this.initColumns();
    this.beginInternalSelectionUpdate();
    ((C1FlexGridBase) this).Select(-1, -1);
    ((RowColCollection) ((C1FlexGridBase) this).Rows).Count = ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed;
    for (int itemIndex = 0; itemIndex < this._viewModel.Count; ++itemIndex)
    {
      Row row = ((C1FlexGridBase) this).Rows.Add();
      this.setViewModelItemIndex(((RowCol) row).Index, itemIndex);
      this.updateRowData(((RowCol) row).Index);
    }
    if (this.EmptyRowAllowAdd)
      this.addEmptyRow();
    this.updateInternalSelection();
    this.endInternalSelectionUpdate();
    ((ScrollableControl) this).EndUpdate();
  }

  private void refreshViewModelData()
  {
    ((ScrollableControl) this).BeginUpdate();
    this.beginInternalSelectionUpdate();
    int row1 = ((C1FlexGridBase) this).Row;
    int col = ((C1FlexGridBase) this).Col;
    ((C1FlexGridBase) this).Select(-1, -1);
    if (this._emptyRowAdded && !this.EmptyRowAllowAdd)
      this.removeEmptyRow();
    int num1 = ((RowColCollection) ((C1FlexGridBase) this).Rows).Count - ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed - (this._emptyRowAdded ? 1 : 0);
    if (num1 > 0)
      ((C1FlexGridBase) this).Rows.RemoveRange(((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed, num1);
    int num2 = ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed;
    int itemIndex = 0;
    while (itemIndex < this._viewModel.Count)
    {
      Row row2 = ((C1FlexGridBase) this).Rows.Insert(num2);
      this.setViewModelItemIndex(((RowCol) row2).Index, itemIndex);
      this.updateRowData(((RowCol) row2).Index);
      ++itemIndex;
      ++num2;
    }
    if (!this._emptyRowAdded && this.EmptyRowAllowAdd)
      this.addEmptyRow();
    if (row1 >= 0 && row1 < ((RowColCollection) ((C1FlexGridBase) this).Rows).Count && col >= 0 && col < ((RowColCollection) ((C1FlexGridBase) this).Cols).Count)
      ((C1FlexGridBase) this).Select(row1, col);
    this.updateInternalSelection();
    this.endInternalSelectionUpdate();
    ((ScrollableControl) this).EndUpdate();
  }

  private void deleteActiveSelection()
  {
    ((ScrollableControl) this).BeginUpdate();
    List<ITxGraphPoint> points = new List<ITxGraphPoint>();
    for (int row = ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed; row < ((RowColCollection) ((C1FlexGridBase) this).Rows).Count; ++row)
    {
      if (((RowCol) ((C1FlexGridBase) this).Rows[row]).Selected)
      {
        ITxGraphPoint viewModelItem = this.getViewModelItem(row);
        if (viewModelItem != null)
          points.Add(viewModelItem);
      }
    }
    if (this.EmptyRowSelected)
      this.clearEmptyRow();
    this._viewModel.BeginUpdate();
    this._viewModel.RemoveRange((IEnumerable<ITxGraphPoint>) points);
    this._viewModel.EndUpdate();
    ((ScrollableControl) this).EndUpdate();
  }

  private void moveItemsUp()
  {
    List<int> items = new List<int>(((RowColCollection) ((C1FlexGridBase) this).Rows.Selected).Count);
    foreach (RowCol rowCol in (IEnumerable) ((C1FlexGridBase) this).Rows.Selected)
    {
      ITxGraphPoint viewModelItem = this.getViewModelItem(rowCol.Index);
      if (viewModelItem != null)
      {
        int num = this._viewModel.IndexOf(viewModelItem);
        if (num > 0)
          items.Add(num);
      }
    }
    this._viewModel.BeginUpdate();
    this._viewModel.MoveUp(items);
    this._viewModel.EndUpdate();
  }

  private void moveItemsDown()
  {
    List<int> items = new List<int>(((RowColCollection) ((C1FlexGridBase) this).Rows.Selected).Count);
    foreach (RowCol rowCol in (IEnumerable) ((C1FlexGridBase) this).Rows.Selected)
    {
      ITxGraphPoint viewModelItem = this.getViewModelItem(rowCol.Index);
      if (viewModelItem != null)
      {
        int num = this._viewModel.IndexOf(viewModelItem);
        if (num < this._viewModel.Count - 1)
          items.Add(num);
      }
    }
    this._viewModel.BeginUpdate();
    this._viewModel.MoveDown(items);
    this._viewModel.EndUpdate();
  }

  private void connectToViewModel()
  {
    if (this._viewModel == null)
      return;
    this._viewModel.Connect((Control) this);
    this.loadViewModelData();
    this.registerToViewModelEvents();
  }

  private void disconnectFromViewModel()
  {
    if (this._viewModel == null)
      return;
    this._viewModel.Disconnect((Control) this);
    this.unregisterToViewModelEvents();
  }

  private void registerToViewModelEvents()
  {
    if (this._viewModel == null)
      return;
    this._viewModel.UpdateStarted += new EventHandler(this._viewModel_UpdateStarted);
    this._viewModel.UpdateEnded += new EventHandler(this._viewModel_UpdateEnded);
    this._viewModel.SelectionChanged += new CApJVLEditorViewModel_SelectionChangedEventHandler(this._viewModel_SelectionChanged);
    this._viewModel.FocusItemChanged += new CApJVLEditorViewModel_FocusItemChangedEventHandler(this._viewModel_FocusItemChanged);
    this._viewModel.ListChanged += new CApJVLEditorViewModel_ListChangedEventHandler(this._viewModel_ListChanged);
    this._viewModel.ListItemPropertyChanged += new CApJVLEditorViewModel_ListItemPropertyChangedEventHandler(this._viewModel_ListItemPropertyChanged);
  }

  private void unregisterToViewModelEvents()
  {
    if (this._viewModel == null)
      return;
    this._viewModel.UpdateStarted -= new EventHandler(this._viewModel_UpdateStarted);
    this._viewModel.UpdateEnded -= new EventHandler(this._viewModel_UpdateEnded);
    this._viewModel.SelectionChanged -= new CApJVLEditorViewModel_SelectionChangedEventHandler(this._viewModel_SelectionChanged);
    this._viewModel.FocusItemChanged -= new CApJVLEditorViewModel_FocusItemChangedEventHandler(this._viewModel_FocusItemChanged);
    this._viewModel.ListChanged += new CApJVLEditorViewModel_ListChangedEventHandler(this._viewModel_ListChanged);
    this._viewModel.ListItemPropertyChanged += new CApJVLEditorViewModel_ListItemPropertyChangedEventHandler(this._viewModel_ListItemPropertyChanged);
  }

  private void registerToGridEvents()
  {
    ((C1FlexGridBase) this).AfterEdit += new RowColEventHandler(this.CUiJVLEditorGrid_AfterEdit);
    ((C1FlexGridBase) this).AfterSelChange += new RangeEventHandler(this.CUiJVLEditorGrid_AfterSelChange);
    ((Control) this).KeyUp += new KeyEventHandler(this.CUiJVLEditorGrid_KeyUp);
    ((Control) this).MouseDown += new MouseEventHandler(this.CUiJVLEditorGrid_MouseDown);
    ((C1FlexGridBase) this).StartEdit += new RowColEventHandler(this.CUiJVLEditorGrid_StartEdit);
    ((C1FlexGridBase) this).LeaveEdit += new RowColEventHandler(this.CUiJVLEditorGrid_LeaveEdit);
    ((C1FlexGridBase) this).KeyPressEdit += new KeyPressEditEventHandler(this.CUiJVLEditorGrid_KeyPressEdit);
    ((C1FlexGridBase) this).ValidateEdit += new ValidateEditEventHandler(this.CUiJVLEditorGrid_ValidateEdit);
    ((C1FlexGridBase) this).ChangeEdit += new EventHandler(this.CUiJVLEditorGrid_ChangeEdit);
    ((C1FlexGridBase) this).SetupEditor += new RowColEventHandler(this.CUiJVLEditorGrid_SetupEditor);
  }

  private void unregisterToGridEvents()
  {
    ((C1FlexGridBase) this).AfterEdit -= new RowColEventHandler(this.CUiJVLEditorGrid_AfterEdit);
    ((C1FlexGridBase) this).AfterSelChange -= new RangeEventHandler(this.CUiJVLEditorGrid_AfterSelChange);
    ((Control) this).KeyUp -= new KeyEventHandler(this.CUiJVLEditorGrid_KeyUp);
    ((Control) this).MouseDown -= new MouseEventHandler(this.CUiJVLEditorGrid_MouseDown);
    ((C1FlexGridBase) this).StartEdit -= new RowColEventHandler(this.CUiJVLEditorGrid_StartEdit);
    ((C1FlexGridBase) this).LeaveEdit -= new RowColEventHandler(this.CUiJVLEditorGrid_LeaveEdit);
    ((C1FlexGridBase) this).KeyPressEdit -= new KeyPressEditEventHandler(this.CUiJVLEditorGrid_KeyPressEdit);
    ((C1FlexGridBase) this).ValidateEdit -= new ValidateEditEventHandler(this.CUiJVLEditorGrid_ValidateEdit);
    ((C1FlexGridBase) this).ChangeEdit -= new EventHandler(this.CUiJVLEditorGrid_ChangeEdit);
    ((C1FlexGridBase) this).SetupEditor -= new RowColEventHandler(this.CUiJVLEditorGrid_SetupEditor);
  }

  private int getViewModelItemIndex(int row)
  {
    object userData = ((RowCol) ((C1FlexGridBase) this).Rows[row]).UserData;
    return userData != null ? (int) userData : -1;
  }

  private void setViewModelItemIndex(int row, int itemIndex)
  {
    ((RowCol) ((C1FlexGridBase) this).Rows[row]).UserData = (object) itemIndex;
  }

  private void clearViewModelItemIndex(int row)
  {
    ((RowCol) ((C1FlexGridBase) this).Rows[row]).UserData = (object) null;
  }

  private ITxGraphPoint getViewModelItem(int row)
  {
    int viewModelItemIndex = this.getViewModelItemIndex(row);
    return viewModelItemIndex >= 0 ? this._viewModel[viewModelItemIndex] : (ITxGraphPoint) null;
  }

  private void updateRowData(int row)
  {
    ((ScrollableControl) this).BeginUpdate();
    foreach (Column col in (IEnumerable) ((C1FlexGridBase) this).Cols)
      this.updateRowData(row, ((RowCol) col).Index);
    ((ScrollableControl) this).EndUpdate();
  }

  private void updateRowData(int row, int col)
  {
    ITxGraphPoint viewModelItem = this.getViewModelItem(row);
    if (viewModelItem == null || col < 0)
      return;
    switch (((C1FlexGridBase) this).Cols[col].Name)
    {
      case "N:":
        this.setNData(row, new int?(this.getViewModelItemIndex(row)));
        break;
      case "X":
        this.setXData(row, new double?(viewModelItem.X));
        break;
      case "Y":
        this.setYData(row, new double?(viewModelItem.Y));
        break;
    }
  }

  private void updateRowDataAfterItemMoved(int oldRow, int newRow)
  {
    ((ScrollableControl) this).BeginUpdate();
    int num1 = oldRow < newRow ? oldRow : newRow;
    int num2 = oldRow < newRow ? newRow : oldRow;
    int row = ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed;
    int itemIndex = 0;
    while (itemIndex < this._viewModel.Count)
    {
      if (row >= num1 && row <= num2)
      {
        this.setViewModelItemIndex(row, itemIndex);
        this.updateRowData(row);
      }
      ++itemIndex;
      ++row;
    }
    ((ScrollableControl) this).EndUpdate();
  }

  private void deleteRowData(int row)
  {
    ((ScrollableControl) this).BeginUpdate();
    int viewModelItemIndex1 = this.getViewModelItemIndex(row);
    if (viewModelItemIndex1 >= 0)
    {
      for (int row1 = row + 1; row1 < ((RowColCollection) ((C1FlexGridBase) this).Rows).Count; ++row1)
      {
        int viewModelItemIndex2 = this.getViewModelItemIndex(row1);
        if (viewModelItemIndex2 > viewModelItemIndex1)
          this.setViewModelItemIndex(row1, viewModelItemIndex2 - 1);
      }
    }
    if (this.EmptyRow != null && ((RowCol) this.EmptyRow).Index == row)
      this.clearEmptyRow();
    else
      ((C1FlexGridBase) this).Rows.Remove(row);
    ((ScrollableControl) this).EndUpdate();
  }

  private int? getNData(int row)
  {
    object userData = this._nCol >= 0 ? ((C1FlexGridBase) this).GetUserData(row, this._nCol) : (object) null;
    return userData != null ? new int?((int) userData) : new int?();
  }

  private void setNData(int row, int? n)
  {
    if (this._nCol < 0)
      return;
    object obj = (object) null;
    if (n.HasValue)
      obj = (object) n.Value;
    ((C1FlexGridBase) this).SetUserData(row, this._nCol, obj);
    ((C1FlexGridBase) this).SetData(row, this._nCol, (object) this.formatNValue(n));
  }

  private double? getXData(int row)
  {
    object data = this._xCol >= 0 ? ((C1FlexGridBase) this).GetData(row, this._xCol) : (object) null;
    return data != null ? new double?((double) data) : new double?();
  }

  private void setXData(int row, double? x)
  {
    if (this._xCol < 0)
      return;
    object obj = (object) null;
    if (x.HasValue)
      obj = (object) x.Value;
    ((C1FlexGridBase) this).SetData(row, this._xCol, obj);
  }

  private double? getYData(int row)
  {
    object data = this._yCol >= 0 ? ((C1FlexGridBase) this).GetData(row, this._yCol) : (object) null;
    return data != null ? new double?((double) data) : new double?();
  }

  private void setYData(int row, double? y)
  {
    if (this._yCol < 0)
      return;
    object obj = (object) null;
    if (y.HasValue)
      obj = (object) y.Value;
    ((C1FlexGridBase) this).SetData(row, this._yCol, obj);
  }

  private string formatNValue(int? n) => n.HasValue ? (n.Value + 1).ToString() : string.Empty;

  private void addEmptyRow()
  {
    if (!this.EmptyRowAllowAdd)
      return;
    ((ScrollableControl) this).BeginUpdate();
    Row row = ((C1FlexGridBase) this).Rows.Add();
    this._emptyRowAdded = row != null;
    this.setNData(((RowCol) row).Index, new int?());
    this.setXData(((RowCol) row).Index, new double?());
    this.setYData(((RowCol) row).Index, new double?());
    ((ScrollableControl) this).EndUpdate();
  }

  private void updateEmptyRow(double? x, double? y)
  {
    Row emptyRow = this.EmptyRow;
    if (emptyRow == null)
      return;
    ((ScrollableControl) this).BeginUpdate();
    this.setXData(((RowCol) emptyRow).Index, x);
    this.setYData(((RowCol) emptyRow).Index, y);
    ((ScrollableControl) this).EndUpdate();
  }

  private void queryEmptyRow(out double? x, out double? y)
  {
    x = new double?();
    y = new double?();
    Row emptyRow = this.EmptyRow;
    if (emptyRow == null)
      return;
    x = this.getXData(((RowCol) emptyRow).Index);
    y = this.getYData(((RowCol) emptyRow).Index);
  }

  private void clearEmptyRow()
  {
    Row emptyRow = this.EmptyRow;
    if (emptyRow == null)
      return;
    ((ScrollableControl) this).BeginUpdate();
    this.setNData(((RowCol) emptyRow).Index, new int?());
    this.setXData(((RowCol) emptyRow).Index, new double?());
    this.setYData(((RowCol) emptyRow).Index, new double?());
    ((ScrollableControl) this).EndUpdate();
  }

  private void removeEmptyRow()
  {
    Row emptyRow = this.EmptyRow;
    if (emptyRow == null)
      return;
    ((ScrollableControl) this).BeginUpdate();
    ((C1FlexGridBase) this).Rows.Remove(emptyRow);
    this._emptyRowAdded = false;
    ((ScrollableControl) this).EndUpdate();
  }

  private void focusEmptyRow()
  {
    Row emptyRow = this.EmptyRow;
    if (emptyRow == null)
      return;
    ((C1FlexGridBase) this).Select(((RowCol) emptyRow).Index, 1);
  }

  private Row EmptyRow
  {
    get
    {
      Row emptyRow = (Row) null;
      if (this._emptyRowAdded && ((RowColCollection) ((C1FlexGridBase) this).Rows).Count > ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed)
        emptyRow = ((C1FlexGridBase) this).Rows[((RowColCollection) ((C1FlexGridBase) this).Rows).Count - 1];
      return emptyRow;
    }
  }

  private bool EmptyRowSelected
  {
    get
    {
      Row emptyRow = this.EmptyRow;
      return emptyRow != null && ((RowCol) emptyRow).Selected;
    }
  }

  private bool EmptyRowFocused
  {
    get
    {
      Row emptyRow = this.EmptyRow;
      return emptyRow != null && ((RowCol) emptyRow).Index == ((C1FlexGridBase) this).Row;
    }
  }

  private bool EmptyRowAllowAdd
  {
    get => this._viewModel != null && this._viewModel.Count < this._viewModel.MaxCount;
  }

  private void updateInternalSelection()
  {
    this.beginInternalSelectionUpdate();
    int itemIndex = this._viewModel.FocusItem != null ? this._viewModel.IndexOf(this._viewModel.FocusItem) : -1;
    if (itemIndex >= 0)
    {
      int num = ((C1FlexGridBase) this).Col;
      if (num < 0)
        num = 1;
      ((C1FlexGridBase) this).Select(this.findViewModelItemRow(itemIndex), num);
    }
    for (int row = ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed; row < ((RowColCollection) ((C1FlexGridBase) this).Rows).Count; ++row)
    {
      ITxGraphPoint viewModelItem = this.getViewModelItem(row);
      if (viewModelItem != null && viewModelItem is ITxGraphSelectablePoint)
        ((RowCol) ((C1FlexGridBase) this).Rows[row]).Selected = (viewModelItem as ITxGraphSelectablePoint).Selected;
    }
    this.endInternalSelectionUpdate();
  }

  private void updateViewModelSelection()
  {
    List<ITxGraphPoint> itxGraphPointList = new List<ITxGraphPoint>();
    foreach (RowCol rowCol in (IEnumerable) ((C1FlexGridBase) this).Rows.Selected)
    {
      ITxGraphPoint viewModelItem = this.getViewModelItem(rowCol.Index);
      if (viewModelItem != null)
        itxGraphPointList.Add(viewModelItem);
    }
    ITxGraphPoint itxGraphPoint = (ITxGraphPoint) null;
    if (((C1FlexGridBase) this).Row >= ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed && ((C1FlexGridBase) this).Col >= 0)
      itxGraphPoint = this.getViewModelItem(((C1FlexGridBase) this).Row);
    this.beginViewModelSelectionUpdate();
    this._viewModel.Selection = (IEnumerable<ITxGraphPoint>) itxGraphPointList;
    this._viewModel.FocusItem = itxGraphPoint;
    this.endViewModelSelectionUpdate();
  }

  private void beginInternalSelectionUpdate()
  {
    ++this._internalSelectionChangeCounter;
    if (this._internalSelectionChangeCounter != 1)
      return;
    ((ScrollableControl) this).BeginUpdate();
  }

  private void endInternalSelectionUpdate()
  {
    if (this._internalSelectionChangeCounter <= 0)
      return;
    --this._internalSelectionChangeCounter;
    if (this._internalSelectionChangeCounter != 0)
      return;
    ((ScrollableControl) this).EndUpdate();
    this.fireInternalSelectionChanged();
  }

  private bool isUpdatingInternalSelection => this._internalSelectionChangeCounter > 0;

  private void beginViewModelSelectionUpdate()
  {
    if (this._viewModel == null)
      return;
    ++this._viewModelSelectionChangeCounter;
    if (this._viewModelSelectionChangeCounter != 1)
      return;
    this._viewModel.BeginUpdate();
  }

  private void endViewModelSelectionUpdate()
  {
    if (this._viewModel == null || this._viewModelSelectionChangeCounter <= 0)
      return;
    --this._viewModelSelectionChangeCounter;
    if (this._viewModelSelectionChangeCounter != 0)
      return;
    this._viewModel.EndUpdate();
  }

  private bool isUpdatingViewModelSelection => this._viewModelSelectionChangeCounter > 0;

  private int findViewModelItemRow(int itemIndex)
  {
    if (this._activeRow >= 0 && this._activeRow < ((RowColCollection) ((C1FlexGridBase) this).Rows).Count && itemIndex == this.getViewModelItemIndex(this._activeRow))
      return this._activeRow;
    for (int row = ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed; row < ((RowColCollection) ((C1FlexGridBase) this).Rows).Count; ++row)
    {
      if (itemIndex == this.getViewModelItemIndex(row))
        return row;
    }
    return -1;
  }

  private void showErrorTooltip(int row, int col, string text)
  {
    if (string.IsNullOrEmpty(text))
    {
      this.hideErrorTooltip();
    }
    else
    {
      if (this._errorTooltip == null)
      {
        this._errorTooltip = new TxErrorCtrl();
        ((Control) this._errorTooltip).Visible = false;
        ((Control) this._errorTooltip).Parent = (Control) ((Control) this).FindForm();
        ((Control) this._errorTooltip).Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
      }
      this._errorTooltip.Location = ((Control) this._errorTooltip).Parent.PointToClient(((Control) this).PointToScreen(new Point(0, ((Control) this).Height)));
      this._errorTooltip.ErrorText = text;
      ((Control) this._errorTooltip).Visible = true;
      ((Control) this._errorTooltip).BringToFront();
      ((Control) this._errorTooltip).Parent.Refresh();
      ((Control) this._errorTooltip).Refresh();
    }
  }

  private void hideErrorTooltip()
  {
    if (this._errorTooltip == null || !((Control) this._errorTooltip).Visible)
      return;
    ((Control) this._errorTooltip).Visible = false;
    ((Control) this._errorTooltip).Parent.Refresh();
  }

  private bool isValidValue(string text, int row, int col, out string errorMsg)
  {
    bool flag = true;
    errorMsg = (string) null;
    if (this._viewModel != null)
    {
      if (((RowCol) ((C1FlexGridBase) this).Cols[col]).DataType != typeof (double) || string.IsNullOrEmpty(text))
        return true;
      double result;
      if (double.TryParse(text, out result))
      {
        if (col == this._xCol)
          flag = this._viewModel.IsValidXValue(result, out errorMsg);
        else if (col == this._yCol)
          flag = this._viewModel.IsValidYValue(result, out errorMsg);
      }
      else
      {
        flag = false;
        errorMsg = string.Empty;
      }
    }
    return flag;
  }

  private double getRoundedValueForEdit(double cellValue)
  {
    return Math.Round((double) this._cellValueBeforeEdit, 5, MidpointRounding.AwayFromZero);
  }

  private bool shouldIgnoreEdit(int row, int col)
  {
    bool flag = false;
    object obj = ((C1FlexGridBase) this)[row, col];
    if (obj != null && obj.GetType() == typeof (double) && this._cellValueBeforeEdit != null && this._cellValueBeforeEdit.GetType() == typeof (double))
    {
      double num = (double) obj;
      if (this.getRoundedValueForEdit((double) this._cellValueBeforeEdit) == num)
        flag = true;
    }
    return flag;
  }

  private void fireInternalSelectionChanged()
  {
    if (this.SelectionChanged == null)
      return;
    this.SelectionChanged((object) this, new EventArgs());
  }

  private void fireCanDoActionChanged()
  {
    if (this.CanDoActionChanged == null)
      return;
    this.CanDoActionChanged((object) this, new EventArgs());
  }

  private void fireInternalDataUpdated()
  {
    if (this.DataUpdated == null)
      return;
    this.DataUpdated((object) this, new EventArgs());
  }

  private void _viewModel_UpdateStarted(object sender, EventArgs e)
  {
    ((ScrollableControl) this).BeginUpdate();
  }

  private void _viewModel_UpdateEnded(object sender, EventArgs e)
  {
    ((ScrollableControl) this).EndUpdate();
  }

  private void _viewModel_FocusItemChanged(object sender, EventArgs args)
  {
    if (this.isUpdatingViewModelSelection)
      return;
    this.updateInternalSelection();
  }

  private void _viewModel_SelectionChanged(object sender, EventArgs args)
  {
    if (this.isUpdatingViewModelSelection)
      return;
    this.updateInternalSelection();
  }

  private void _viewModel_ListChanged(
    object sender,
    CApJVLEditorViewModel_ListChangedEventArgs args)
  {
    switch (args.ListChangedType)
    {
      case CApJVLEditorViewModel_ListChangedType.ItemAdded:
        Row emptyRow = this.EmptyRow;
        int row = -1;
        if (this._activeRow >= ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed && this._activeRow <= ((RowColCollection) ((C1FlexGridBase) this).Rows).Count)
          row = this._activeRow;
        else if (emptyRow != null)
          row = ((RowCol) emptyRow).Index;
        if (row >= 0)
        {
          this.setViewModelItemIndex(row, args.NewIndex);
          this.updateRowData(row);
          if (emptyRow != null && row == ((RowCol) emptyRow).Index)
          {
            if (this.EmptyRowAllowAdd)
            {
              this.addEmptyRow();
              this.focusEmptyRow();
              break;
            }
            this._emptyRowAdded = false;
            break;
          }
          break;
        }
        break;
      case CApJVLEditorViewModel_ListChangedType.ItemDeleted:
        int viewModelItemRow1 = this.findViewModelItemRow(args.NewIndex);
        if (viewModelItemRow1 >= 0)
        {
          this.deleteRowData(viewModelItemRow1);
          if (!this._emptyRowAdded && this.EmptyRowAllowAdd)
          {
            this.addEmptyRow();
            break;
          }
          break;
        }
        break;
      case CApJVLEditorViewModel_ListChangedType.ItemMoved:
        int viewModelItemRow2 = this.findViewModelItemRow(args.OldIndex);
        int viewModelItemRow3 = this.findViewModelItemRow(args.NewIndex);
        if (viewModelItemRow2 >= 0 && viewModelItemRow3 >= 0)
        {
          this.updateRowDataAfterItemMoved(viewModelItemRow2, viewModelItemRow3);
          break;
        }
        break;
      case CApJVLEditorViewModel_ListChangedType.ItemChanged:
        int viewModelItemRow4 = this.findViewModelItemRow(args.NewIndex);
        if (viewModelItemRow4 >= 0)
        {
          this.updateRowData(viewModelItemRow4);
          break;
        }
        break;
      default:
        this.refreshViewModelData();
        break;
    }
    this.fireInternalDataUpdated();
  }

  private void _viewModel_ListItemPropertyChanged(
    object sender,
    CApJVLEditorViewModel_ListItemPropertyChangedEventArgs args)
  {
    switch (args.PropertyName)
    {
      case "X":
        int viewModelItemRow1 = this.findViewModelItemRow(args.ItemIndex);
        if (viewModelItemRow1 >= 0)
        {
          this.updateRowData(viewModelItemRow1, this._xCol);
          break;
        }
        break;
      case "Y":
        int viewModelItemRow2 = this.findViewModelItemRow(args.ItemIndex);
        if (viewModelItemRow2 >= 0)
        {
          this.updateRowData(viewModelItemRow2, this._yCol);
          break;
        }
        break;
      case "Selected":
        int viewModelItemRow3 = this.findViewModelItemRow(args.ItemIndex);
        if (viewModelItemRow3 >= 0)
        {
          this.beginInternalSelectionUpdate();
          ITxGraphPoint viewModelItem = this.getViewModelItem(viewModelItemRow3);
          if (viewModelItem != null && viewModelItem is ITxGraphSelectablePoint)
            ((RowCol) ((C1FlexGridBase) this).Rows[viewModelItemRow3]).Selected = (viewModelItem as ITxGraphSelectablePoint).Selected;
          this.endInternalSelectionUpdate();
          break;
        }
        break;
    }
    this.fireInternalDataUpdated();
  }

  private void CUiJVLEditorGrid_AfterEdit(object sender, RowColEventArgs e)
  {
    if (this.shouldIgnoreEdit(e.Row, e.Col))
    {
      ((C1FlexGridBase) this)[e.Row, e.Col] = this._cellValueBeforeEdit;
      this.fireCanDoActionChanged();
    }
    else
    {
      Row emptyRow = this.EmptyRow;
      if (emptyRow != null && e.Row == ((RowCol) emptyRow).Index)
      {
        double? x;
        double? y;
        this.queryEmptyRow(out x, out y);
        if (x.HasValue && y.HasValue)
        {
          this._activeRow = e.Row;
          ITxGraphPoint point = this._viewModel.CreatePoint(x.Value, y.Value);
          this._viewModel.BeginUpdate();
          this._viewModel.Add(point);
          this._viewModel.EndUpdate();
          this._activeRow = -1;
        }
        else
          this.fireInternalDataUpdated();
      }
      else
      {
        ITxGraphPoint viewModelItem = this.getViewModelItem(e.Row);
        if (viewModelItem == null)
          return;
        switch (((C1FlexGridBase) this).Cols[e.Col].Name)
        {
          case "X":
            double? xdata = this.getXData(e.Row);
            if (!xdata.HasValue)
              break;
            this._viewModel.BeginUpdate();
            viewModelItem.X = xdata.Value;
            this._viewModel.EndUpdate();
            break;
          case "Y":
            double? ydata = this.getYData(e.Row);
            if (!ydata.HasValue)
              break;
            this._viewModel.BeginUpdate();
            viewModelItem.Y = ydata.Value;
            this._viewModel.EndUpdate();
            break;
        }
      }
    }
  }

  protected virtual void OnKeyDownEdit(KeyEditEventArgs e)
  {
    if (this._editorValidState && (e.KeyCode == Keys.Return || e.KeyCode == Keys.Tab))
    {
      e.Handled = true;
      ((C1FlexGridBase) this).FinishEditing();
      if (((C1FlexGridBase) this).Editor != null)
        return;
      if (e.KeyCode == Keys.Return)
      {
        if (e.Row >= ((RowColCollection) ((C1FlexGridBase) this).Rows).Count - 1)
          return;
        ((C1FlexGridBase) this).Select(e.Row + 1, 1);
      }
      else if (e.Col < ((RowColCollection) ((C1FlexGridBase) this).Cols).Count - 1)
      {
        ((C1FlexGridBase) this).Select(e.Row, e.Col + 1);
      }
      else
      {
        if (e.Col != ((RowColCollection) ((C1FlexGridBase) this).Cols).Count - 1 || e.Row >= ((RowColCollection) ((C1FlexGridBase) this).Rows).Count - 1)
          return;
        ((C1FlexGridBase) this).Select(e.Row + 1, 1);
      }
    }
    else
      ((C1FlexGridBase) this).OnKeyDownEdit(e);
  }

  private void CUiJVLEditorGrid_AfterSelChange(object sender, RangeEventArgs e)
  {
    if (this.isUpdatingInternalSelection)
      return;
    this.updateViewModelSelection();
    this.fireInternalSelectionChanged();
  }

  private void CUiJVLEditorGrid_ChangeEdit(object sender, EventArgs e)
  {
    string errorMsg;
    if (!this.isValidValue(((C1FlexGridBase) this).Editor.Text, this._editorRow, this._editorCol, out errorMsg))
    {
      ((C1FlexGridBase) this).Editor.BackColor = Color.Red;
      this.showErrorTooltip(this._editorRow, this._editorCol, errorMsg);
      this._editorValidState = false;
      this.fireCanDoActionChanged();
    }
    else
    {
      ((C1FlexGridBase) this).Editor.BackColor = this._editorBackColor;
      this.hideErrorTooltip();
      this._editorValidState = true;
      this.fireCanDoActionChanged();
    }
  }

  private void CUiJVLEditorGrid_ValidateEdit(object sender, ValidateEditEventArgs e)
  {
    if (this.isValidValue(((C1FlexGridBase) this).Editor.Text, this._editorRow, this._editorCol, out string _))
      return;
    e.Cancel = true;
    this._editorValidState = false;
    this.fireCanDoActionChanged();
  }

  private void CUiJVLEditorGrid_KeyPressEdit(object sender, KeyPressEditEventArgs e)
  {
    if (((RowCol) ((C1FlexGridBase) this).Cols[this._editorCol]).DataType != typeof (double) || char.IsDigit(e.KeyChar))
      return;
    if (char.IsLetter(e.KeyChar))
    {
      if (e.KeyChar == 'e' || e.KeyChar == 'E')
        return;
      e.Handled = true;
    }
    else
    {
      switch (e.KeyChar)
      {
        case '+':
          break;
        case ',':
          break;
        case '-':
          break;
        case '.':
          break;
        default:
          if (e.KeyChar == '\b' || e.KeyChar == '\r' || e.KeyChar == '\t' || e.KeyChar == '\u001B')
            break;
          e.Handled = true;
          break;
      }
    }
  }

  private void CUiJVLEditorGrid_LeaveEdit(object sender, RowColEventArgs e)
  {
    this.resumeParentFormKeyPreview();
    this._editorValidState = true;
    this.hideErrorTooltip();
    this.fireCanDoActionChanged();
  }

  private void CUiJVLEditorGrid_StartEdit(object sender, RowColEventArgs e)
  {
    this.suspendParentFormKeyPreview();
    ((C1FlexGridBase) this).Editor.BackColor = ((C1FlexGridBase) this).GetCellStyleDisplay(e.Row, e.Col).BackColor;
    this._editorBackColor = ((C1FlexGridBase) this).Editor.BackColor;
    this._editorRow = e.Row;
    this._editorCol = e.Col;
    this._editorValidState = true;
    this._cellValueBeforeEdit = ((C1FlexGridBase) this)[e.Row, e.Col];
    this.fireCanDoActionChanged();
  }

  private void CUiJVLEditorGrid_MouseDown(object sender, MouseEventArgs e)
  {
    HitTestInfo hitTestInfo = ((C1FlexGridBase) this).HitTest(e.X, e.Y);
    if (((HitTestInfo) ref hitTestInfo).Type == null)
    {
      ((C1FlexGridBase) this).Select(-1, -1);
    }
    else
    {
      if (((HitTestInfo) ref hitTestInfo).Type != 1)
        return;
      int row = ((HitTestInfo) ref hitTestInfo).Row;
      int column = ((HitTestInfo) ref hitTestInfo).Column;
      if (row < ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed || column < ((RowColCollection) ((C1FlexGridBase) this).Cols).Fixed || !((RowCol) ((C1FlexGridBase) this).Cols[((C1FlexGridBase) this).Col]).AllowEditing || e.Button != MouseButtons.Left || (Control.ModifierKeys & Keys.Control) == Keys.Control || (Control.ModifierKeys & Keys.Shift) == Keys.Shift)
        return;
      ((C1FlexGridBase) this).StartEditing(row, column);
    }
  }

  private void CUiJVLEditorGrid_KeyUp(object sender, KeyEventArgs e)
  {
    if (e.KeyCode == Keys.F2)
    {
      if (((C1FlexGridBase) this).Row < ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed || ((C1FlexGridBase) this).Col < ((RowColCollection) ((C1FlexGridBase) this).Cols).Fixed || !((RowCol) ((C1FlexGridBase) this).Cols[((C1FlexGridBase) this).Col]).AllowEditing)
        return;
      ((C1FlexGridBase) this).StartEditing(((C1FlexGridBase) this).Row, ((C1FlexGridBase) this).Col);
    }
    else if (e.KeyCode == Keys.Delete)
    {
      if (!this.CanDeleteActiveSelection)
        return;
      this.deleteActiveSelection();
    }
    else
    {
      if (e.KeyCode != Keys.A || Control.ModifierKeys != Keys.Control)
        return;
      this.beginInternalSelectionUpdate();
      for (int index = ((RowColCollection) ((C1FlexGridBase) this).Rows).Fixed; index < ((RowColCollection) ((C1FlexGridBase) this).Rows).Count; ++index)
        ((RowCol) ((C1FlexGridBase) this).Rows[index]).Selected = true;
      this.endInternalSelectionUpdate();
      this.updateViewModelSelection();
    }
  }

  private void CUiJVLEditorGrid_SetupEditor(object sender, RowColEventArgs e)
  {
    if (((C1FlexGridBase) this).Editor == null)
      return;
    this._cellValueBeforeEdit = ((C1FlexGridBase) this)[e.Row, e.Col];
    if (this._cellValueBeforeEdit == null || !(this._cellValueBeforeEdit.GetType() == typeof (double)))
      return;
    ((C1FlexGridBase) this).Editor.Text = this.getRoundedValueForEdit((double) this._cellValueBeforeEdit).ToString();
  }

  protected virtual void Dispose(bool disposing)
  {
    if (disposing && this.components != null)
      this.components.Dispose();
    base.Dispose(disposing);
  }

  private void InitializeComponent()
  {
    ((ISupportInitialize) this).BeginInit();
    ((Control) this).SuspendLayout();
    ((ISupportInitialize) this).EndInit();
    ((Control) this).ResumeLayout(false);
  }
}
